#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/ioctl.h>
#include <net/if.h>
int main(int argc, char *argv[])
{
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);

    // 创建Server端地址结构体
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;                   // 使用ipv4
    addr.sin_port = htons(11111);                // 端口   htons()  主机字节序转网络字节序host to net
    addr.sin_addr.s_addr = inet_addr("0.0.0.0"); // ip  inet_addr() 将主机IP 转成 网络IP

    bind(sockfd, (struct sockaddr *)&addr, sizeof(addr));
    listen(sockfd, 5);

    struct sockaddr_in myAddr = {0};
    socklen_t len = sizeof(myAddr);

    getsockname(sockfd, (struct sockaddr *)&myAddr, &len);
    printf("IP: %s\n", inet_ntoa(myAddr.sin_addr));
    printf("Port: %d\n", ntohs(myAddr.sin_port));

    while (1)
    {
        // 创建Client端地址结构体
        struct sockaddr_in ClientAddr;
        memset(&addr, 0, sizeof(addr));
        int ClientAddr_len = sizeof(ClientAddr);
        int connectfd = accept(sockfd, (struct sockaddr *)&ClientAddr, &ClientAddr_len);
        printf("Client Connected! ip: %s, port: %d\n", inet_ntoa(ClientAddr.sin_addr), ntohs(ClientAddr.sin_port));
        // ==============
        struct sockaddr_in myAddr = {0};
        socklen_t len = sizeof(myAddr);

        getsockname(sockfd, (struct sockaddr *)&myAddr, &len);
        printf("myAddr IP: %s\n", inet_ntoa(myAddr.sin_addr));
        printf("myAddr Port: %d\n", ntohs(myAddr.sin_port));

        // =============
        struct sockaddr_in otherAddr = {0};
        socklen_t otherAddr_len = sizeof(otherAddr);

        // 获取对端套接字的地址信息
        getpeername(connectfd, (struct sockaddr *)&otherAddr, &otherAddr_len);
        printf("other IP: %s\n", inet_ntoa(otherAddr.sin_addr));
        printf("other Port: %d\n", ntohs(otherAddr.sin_port));
    }

    // // 客户端没有绑定 客户端的ip和端口  连接之后获取到客户端的 ip和端口
    // // ===================================
    // struct sockaddr_in myAddr = {0};
    // socklen_t len = sizeof(myAddr);

    // getsockname(sockfd, (struct sockaddr *)&myAddr, &len);
    // printf("IP: %s\n", inet_ntoa(myAddr.sin_addr));
    // printf("Port: %d\n", ntohs(myAddr.sin_port));

    // struct sockaddr_in otherAddr = {0};
    // socklen_t otherAddr_len = sizeof(otherAddr);

    // // 获取对端套接字的地址信息
    // getpeername(sockfd, (struct sockaddr *)&otherAddr, &otherAddr_len);
    // printf("server IP: %s\n", inet_ntoa(otherAddr.sin_addr));
    // printf("server Port: %d\n", ntohs(otherAddr.sin_port));
    // // ==============================

    return 0;
}